﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions.Readers;
using TSU.FAMC.ComputerEngineering.Classes.BooleanMaths.Functions;
using TSU.FAMC.ComputerEngineering.Classes.Circuits;
using TSU.FAMC.ComputerEngineering.Classes.Circuits.Readers;
using TSU.FAMC.ComputerEngineering.Classes.OrandTrees;
using TSU.FAMC.ComputerEngineering.Classes.OrandTrees.Readers;

namespace CircuitVerification
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            openFileDialog2.ShowDialog();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.FileNames.Length == 0)
            {
                MessageBox.Show("Не выбраны файлы систем!");
                return;
            }

            if (openFileDialog2.FileNames.Length == 0)
            {
                MessageBox.Show("Не выбраны файлы схем!");
                return;
            }

            if (openFileDialog1.FileNames.Length != openFileDialog2.FileNames.Length)
            {
                MessageBox.Show("Выбрано разное количество файлов систем и схем!");
                return;
            }

            var errorCounter = 0;
            reportText.Clear();
            for (var j = 0; j < openFileDialog1.FileNames.Length; j++)
            {
                var fileName1 = openFileDialog1.FileNames[j];
                var fileName2 = openFileDialog2.FileNames[j];


                // loading system
                var fileStr = String.Empty;

                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName1);
                    fileStr = streamReader.ReadToEnd();
                }
                catch (Exception ex)
                {
                    errorCounter++;
                    reportText.Text += string.Format("Ошибка: не удалось прочитать файл системы {0}. Подрбнее: {1} \r\n\r\n", fileName1, ex.Message);
                    continue;
                }


                // replacing all '_' symbols within '-'
                fileStr = fileStr.Replace('_', '-');

                // reading system
                var systemOriginal = new BooleanSystem();
                var readerFR = new BooleanSystemReaderPlafr();
                var readerFD = new BooleanSystemReaderPlafd();

                // trying read FR system
                try
                {
                    readerFR.Input = fileStr;
                    readerFR.System = systemOriginal;
                    readerFR.Read();
                }
                catch (Exception)
                {
                    // it's not an FR format, trying FD
                    try
                    {
                        readerFD.Input = fileStr;
                        readerFD.System = systemOriginal;
                        readerFD.Read();
                    }
                    catch (Exception ex)
                    {
                        errorCounter++;
                        reportText.Text += string.Format("Ошибка: не удалось прочитать систему булевых функций из файла {0}. Подрбнее: {1} \r\n\r\n", fileName1, ex.Message);
                        continue;
                    }
                }


                // loading circuit
                var circuitStr = String.Empty;

                try
                {
                    // reading file
                    var streamReader = new StreamReader(fileName2);
                    circuitStr = streamReader.ReadToEnd();
                }
                catch (Exception ex)
                {
                    errorCounter++;
                    reportText.Text += string.Format("Ошибка: не удалось прочитать файл схемы {0}. Подрбнее: {1} \r\n\r\n", fileName2, ex.Message);
                    continue;
                }


                // building circuit
                var circuit = new Circuit();

                // building circuit
                var readerCircuit = new CircuitReaderPlain();
                readerCircuit.Input = circuitStr;
                readerCircuit.Read();
                circuit = readerCircuit.Circuit;

                // building ORANDTree
                var tree = new OrandTree();

                // reading tree from circuit
                var readerORANDTree = new OrandTreeReaderCircuit();
                readerORANDTree.Input = circuit;
                readerORANDTree.Read();
                tree = readerORANDTree.Tree;

                // tree system
                var treeSystem = new BooleanSystem();

                // reading system from ORANDTree
                var readerSytemFromORANDTree = new BooleanSystemReaderOrandTree();
                readerSytemFromORANDTree.Input = tree;
                readerSytemFromORANDTree.System = treeSystem;
                readerSytemFromORANDTree.Read();

                // setting Domain0 to tree system because circuit represents only Domain1
                for (var i = 0; i < systemOriginal.Functions.Count; i++)
                {
                    treeSystem.Functions[i].Domain0 = systemOriginal.Functions[i].Domain0;
                }

                // checking tree system
                if (!treeSystem.IsRealizationOf(systemOriginal))
                {
                    errorCounter++;
                    reportText.Text += string.Format("Ошибка верификации схемы {0} по исходной системе булевых функций! \r\n\r\n", fileName1);
                }
            }

            if (errorCounter == 0)
            {
                MessageBox.Show("Схемы построены верно.");
            }
        }
    }
}
